﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;

using JoinGame = Wormhole.UI.Application.Dialogs.JoinGame;

using SG1 = Wormhole.Engine.CardLibrary.SG1;


namespace Wormhole.UI.Application
{
	/// <summary>
	/// Interaction logic for Main.xaml
	/// </summary>
	public partial class Main : Window
	{
		#region Declarations

		#region Details Dialog
		/// <summary>
		/// The dialog that will be used to display card details.
		/// </summary>
		protected CardDetails detailsDialog;
		#endregion

		#region Connect Dialog
		JoinGame.Connect connectDialog;
		#endregion

		#region Games Dialog
		protected JoinGame.OpenGames gamesDialog;
		#endregion

		#region Wait Dialog
		protected JoinGame.Wait waitDialog;
		#endregion

		#endregion

		#region Properties

		#region Game
		/// <summary>
		/// The Game Engine object.
		/// </summary>
		protected Engine.Game game { get; set; }
		#endregion

		#endregion

		#region Start Game
		/// <summary>
		/// Start the game
		/// </summary>
		private void StartGame()
		{
			// configure the hero area
			this.HeroArea.DetailsDialog = this.detailsDialog;
			this.HeroArea.Game = this.game;

			// configure the villian area
			this.VillianArea.DetailsDialog = this.detailsDialog;
			this.VillianArea.Game = this.game;

			// choose the area to display
			this.HeroArea.Visibility = Visibility.Hidden;
			this.VillianArea.Visibility = Visibility.Hidden;

			if (this.game.GameTurn.HeroPlayer == this.game.Player1)
				this.HeroArea.Visibility = Visibility.Visible;
			else
				this.VillianArea.Visibility = Visibility.Visible;

			// close the wait dialog
			this.waitDialog.Done = true;
			this.waitDialog.Close();

			// start the new game
			this.game.Start();
		}
		#endregion

		#region InitializePlayerDeck
		/// <summary>
		/// Initize the card deck for a player.
		/// </summary>
		/// <param name="player">The player to initialize the deck for.</param>
		private void InitializePlayerDeck(Engine.Player.Player player)
		{
			// team
			player.Deck.Add(new SG1.Cards.Hero.Character.SG1C105(player));
			player.Deck.Add(new SG1.Cards.Hero.Character.SG1C88(player));
			player.Deck.Add(new SG1.Cards.Hero.Character.SG1C95(player));
			player.Deck.Add(new SG1.Cards.Hero.Character.SG1S93(player));

			// support characters
			player.Deck.Add(new SG1.Cards.Hero.Character.SG1C66(player));
			player.Deck.Add(new SG1.Cards.Hero.Character.SG1C66(player));
			player.Deck.Add(new SG1.Cards.Hero.Character.SG1C66(player));
			player.Deck.Add(new SG1.Cards.Hero.Character.SG1C65(player));
			player.Deck.Add(new SG1.Cards.Hero.Character.SG1C65(player));
			player.Deck.Add(new SG1.Cards.Hero.Character.SG1C65(player));

			// events
			player.Deck.Add(new SG1.Cards.Hero.Event.SG1C116(player));
			player.Deck.Add(new SG1.Cards.Hero.Event.SG1C116(player));
			player.Deck.Add(new SG1.Cards.Hero.Event.SG1C131(player));
			player.Deck.Add(new SG1.Cards.Hero.Event.SG1C131(player));
			player.Deck.Add(new SG1.Cards.Hero.Event.SG1C131(player));
			player.Deck.Add(new SG1.Cards.Hero.Event.SG1C132(player));
			player.Deck.Add(new SG1.Cards.Hero.Event.SG1C132(player));
			player.Deck.Add(new SG1.Cards.Hero.Event.SG1C132(player));

			// gear
			player.Deck.Add(new SG1.Cards.Hero.Gear.SG1C142(player));
			player.Deck.Add(new SG1.Cards.Hero.Gear.SG1C142(player));
			player.Deck.Add(new SG1.Cards.Hero.Gear.SG1C143(player));
			player.Deck.Add(new SG1.Cards.Hero.Gear.SG1C143(player));
			player.Deck.Add(new SG1.Cards.Hero.Gear.SG1C148(player));
			player.Deck.Add(new SG1.Cards.Hero.Gear.SG1C148(player));

			// missions
			player.Deck.Add(new SG1.Cards.Hero.Mission.SG1S160(player));
			player.Deck.Add(new SG1.Cards.Hero.Mission.SG1S162(player));
			player.Deck.Add(new SG1.Cards.Hero.Mission.SG1S166(player));
			player.Deck.Add(new SG1.Cards.Hero.Mission.SG1S171(player));
			player.Deck.Add(new SG1.Cards.Hero.Mission.SG1S185(player));
			player.Deck.Add(new SG1.Cards.Hero.Mission.SG1S174(player));
			player.Deck.Add(new SG1.Cards.Hero.Mission.SG1S179(player));
			player.Deck.Add(new SG1.Cards.Hero.Mission.SG1S194(player));
			player.Deck.Add(new SG1.Cards.Hero.Mission.SG1S196(player));
			player.Deck.Add(new SG1.Cards.Hero.Mission.SG1S199(player));
			player.Deck.Add(new SG1.Cards.Hero.Mission.SG1S200(player));
			player.Deck.Add(new SG1.Cards.Hero.Mission.SG1S201(player));

			// adversary
			player.Deck.Add(new SG1.Cards.Villain.Adversary.SG1S1(player));
			player.Deck.Add(new SG1.Cards.Villain.Adversary.SG1S1(player));
			player.Deck.Add(new SG1.Cards.Villain.Adversary.SG1C26(player));
			player.Deck.Add(new SG1.Cards.Villain.Adversary.SG1C26(player));

			// obstacle
			player.Deck.Add(new SG1.Cards.Villain.Obstacle.SG1C216(player));
			player.Deck.Add(new SG1.Cards.Villain.Obstacle.SG1C216(player));

			player.Deck.Add(new SG1.Cards.Villain.Obstacle.SG1C231(player));
			player.Deck.Add(new SG1.Cards.Villain.Obstacle.SG1C231(player));
			player.Deck.Add(new SG1.Cards.Villain.Obstacle.SG1C231(player));

			player.Deck.Add(new SG1.Cards.Villain.Obstacle.SG1C239(player));
			player.Deck.Add(new SG1.Cards.Villain.Obstacle.SG1C239(player));

			player.Deck.Add(new SG1.Cards.Villain.Obstacle.SG1C252(player));
			player.Deck.Add(new SG1.Cards.Villain.Obstacle.SG1C252(player));

			player.Deck.Add(new SG1.Cards.Villain.Obstacle.SG1C258(player));
			player.Deck.Add(new SG1.Cards.Villain.Obstacle.SG1C258(player));

			player.Deck.Add(new SG1.Cards.Villain.Obstacle.SG1C276(player));
			player.Deck.Add(new SG1.Cards.Villain.Obstacle.SG1C276(player));
			player.Deck.Add(new SG1.Cards.Villain.Obstacle.SG1C276(player));

			player.Deck.Add(new SG1.Cards.Villain.Obstacle.SG1C278(player));
			player.Deck.Add(new SG1.Cards.Villain.Obstacle.SG1C278(player));
			player.Deck.Add(new SG1.Cards.Villain.Obstacle.SG1C278(player));

			player.Deck.Add(new SG1.Cards.Villain.Obstacle.SG1C281(player));
			player.Deck.Add(new SG1.Cards.Villain.Obstacle.SG1C281(player));
			player.Deck.Add(new SG1.Cards.Villain.Obstacle.SG1C281(player));
		}
		#endregion

		#region Event Handlers
		/// <summary>
		/// On Closing
		/// </summary>
		protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
		{
			base.OnClosing(e);
			this.detailsDialog.Close();
		}

		private void game_GameStarted()
		{
			this.Dispatcher.Invoke(
				DispatcherPriority.Normal,
				(System.Windows.Forms.MethodInvoker)delegate() {
					this.StartGame();
			});
		}
		#endregion

		public Main()
		{
			InitializeComponent();

			// create the details dialog
			this.detailsDialog = new CardDetails();
			this.detailsDialog.Owner = this.Owner;

			this.game = new Wormhole.Engine.Game();
			this.game.GameStarted += new Wormhole.Engine.Game.GameStartedDelegate(game_GameStarted);

			this.InitializePlayerDeck(this.game.Player1);
			this.InitializePlayerDeck(this.game.Player2);
	
			//this.InitializePlayers();
		}

		protected override void OnContentRendered(EventArgs e)
		{
			this.DisplayConnectDialog();
			this.DisplayGamesDialog();

			if (!this.game.Joined)
				this.Close();

			if (this.game.Joined)
			{
				// create the please wait dialog
				this.waitDialog = new Wormhole.UI.Application.Dialogs.JoinGame.Wait();
				this.waitDialog.Owner = this;

				// display the dialog
				this.waitDialog.ShowDialog();
			}

			base.OnContentRendered(e);
		}

		protected override void OnClosed(EventArgs e)
		{
			this.game.Disconnect();
			base.OnClosed(e);
		}

		private void DisplayConnectDialog()
		{
			// create the connect dialog
			this.connectDialog = new Wormhole.UI.Application.Dialogs.JoinGame.Connect();
			this.connectDialog.Owner = this;
			this.connectDialog.Game = this.game;

			// display the dialog
			this.connectDialog.ShowDialog();
		}

		#region Display Games Dialog
		/// <summary>
		/// Display the games dialog.
		/// </summary>
		private void DisplayGamesDialog()
		{
			// create the dialog
			this.gamesDialog = new Wormhole.UI.Application.Dialogs.JoinGame.OpenGames();
			this.gamesDialog.Owner = this;
			this.gamesDialog.Game = this.game;

			// display the dialog
			this.gamesDialog.ShowDialog();
		}
		#endregion
	}
}
